# 给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。
#
#
#
#
#
#
#  示例 1:
#
#  输入: amount = 5, coins = [1, 2, 5]
# 输出: 4
# 解释: 有四种方式可以凑成总金额:
# 5=5
# 5=2+2+1
# 5=2+1+1+1
# 5=1+1+1+1+1
#
#
#  示例 2:
#
#  输入: amount = 3, coins = [2]
# 输出: 0
# 解释: 只用面额2的硬币不能凑成总金额3。
#
#
#  示例 3:
#
#  输入: amount = 10, coins = [10]
# 输出: 1
#
#
#
#
#  注意:
#
#  你可以假设：
#
#
#  0 <= amount (总金额) <= 5000
#  1 <= coin (硬币面额) <= 5000
#  硬币种类不超过 500 种
#  结果符合 32 位符号整数
#
#  👍 220 👎 0

from typing import List


# leetcode submit region begin(Prohibit modification and deletion)
class Solution:
    def change(self, amount: int, coins: List[int]) -> int:

        dp = [0 for _ in range(0, amount + 1)]

        dp[0] = 1

        res = {}

        # dict 记录每种金额的解法
        for a in range(0, amount + 1):
            res[a] = []

        res[0] = [[]]
        # 外层循环是 硬币，这样是为了去重，因为是qui组合数，而不是排列数 ,只会从前往后取硬币
        for coin in coins:
            for a in range(1, amount + 1):
                if a >= coin:

                    for r in res[a - coin]:
                        # 子问题的解法复制一份
                        s = r[:]
                        # 加上当前硬币
                        s.append(coin)
                        # 把当前解法加入到结果集合中
                        res[a].append(s)

                    dp[a] = dp[a] + dp[a - coin]

        for k in res.keys():
            print(k, res[k])
        return dp[amount]


# leetcode submit region end(Prohibit modification and deletion)


print(Solution().change(5, [1]))

res = [[1, 2, 3], [4, 5, 6]]

c = res[0][:]
c.append(100)

print(c)
